pub trait Nname {
    fn get_name(&self) -> String;
}

pub struct Person {
    pub name: String,
    pub kk: String,
}

impl Nname for Person {
    fn get_name(&self) -> String {
        format!("{} - {}", self.name, self.kk)
    }
}

struct Personsub {
    name: String,
    date: String,
}

impl Nname for Personsub {
    fn get_name(&self) -> String {
        format!("{} - {}", self.name, self.date)
    }
}

trait Constraint {
    fn b(&self) -> i32;
}

trait Constraint2 {
    fn c(&self) -> String;
}

trait Constraint3 {
    fn c(&self) -> String;
}

fn fn_constraint(k: impl Constraint, v: impl Constraint2) -> String {
    v.c()
}
fn fn_constraint_1<K: Constraint, V: Constraint2>(k: K, v: V) -> String {
    v.c()
}

fn fn_constraint1(k: impl Constraint + Constraint2, v: impl Constraint2) -> String {
    k.c()
}
fn fn_constraint1_1<K: Constraint + Constraint2, V: Constraint2>(k: K, v: V) -> String {
    k.c()
}

fn fn_constraint2(
    k: impl Constraint + Constraint2,
    v: impl Constraint2 + Constraint3,
    f: impl Constraint + Constraint3,
) -> String {
    k.c()
}

fn fn_constraint2_2<
    K: Constraint + Constraint2,
    V: Constraint2 + Constraint3,
    F: Constraint + Constraint3,
>(
    k: K,
    v: V,
    f: F,
) -> String {
    k.c()
}

fn fn_constraint2_3<K, V, F>(k: K, v: V, f: F) -> String
where
    K: Constraint + Constraint2,
    V: Constraint2 + Constraint3,
    F: Constraint + Constraint3,
{
    k.c()
}

// 使用impl只能返回确定(！！)的同一种类型，返回可能不同类型的代码会报错

